﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Smart.Hotfix
{
    [ObjectSystem]
    public class ObjectPoolAwakeSystem : AwakeSystem<ObjectPool, EventSystem,Transform>
    {
        public override void Awake(ObjectPool self, EventSystem eventSystem,Transform parent)
        {
            self.Awake(eventSystem,parent);
        }
    }

    public class ObjectPool : ComponentView
    {
        private readonly Dictionary<Type, Queue<Component>> dictionary = new Dictionary<Type, Queue<Component>>();

        public override void Awake(EventSystem eventSystem, Transform parent)
        {
            base.Awake(eventSystem, parent);
            gameObject.name = "组件对象池";
        }

        public override void Dispose()
        {
            if(!this.Disposed)
            {
                this.Clear();
            }
            base.Dispose();
        }

        public Component Get(Type type)
        {
            Component obj;
            if (!this.dictionary.TryGetValue(type, out Queue<Component> queue))
            {
                obj = (Component)Activator.CreateInstance(type);
            }
            else if (queue.Count == 0)
            {
                obj = (Component)Activator.CreateInstance(type);
            }
            else
            {
                obj = queue.Dequeue();
            }

            obj.IsFromPool = true;
            return obj;
        }

        public T Get<T>() where T : Component
        {
            T t = (T)this.Get(typeof(T));
            return t;
        }

        public void Put(Component obj)
        {
            Type type = obj.GetType();
            if (!this.dictionary.TryGetValue(type, out Queue<Component> queue))
            {
                queue = new Queue<Component>(32);
                this.dictionary.Add(type, queue);
            }
            queue.Enqueue(obj);
        }

        public void Clear()
        {
            foreach (var kv in this.dictionary)
            {
                var queue = kv.Value;
                while (queue.Count > 0)
                {
                    var component = queue.Dequeue();
                    component.IsFromPool = false;
                    component.Dispose();
                }
            }
            this.dictionary.Clear();
        }
    }
}